package com.example.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.apis.wemedia.IWemediaClient;
import com.example.article.mapper.ApArticleMapper;
import com.example.article.service.HotArticleService;
import com.example.common.constants.ArticleConstants;
import com.example.common.redis.RedisCache;
import com.example.model.article.pojos.ApArticle;
import com.example.model.article.vos.HotArticleVo;
import com.example.model.common.dtos.ResponseResult;
import com.example.model.wemedia.pojos.WmChannel;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;


//    @Scheduled(cron = "0 0 1 * * ?")
    @Override
    public void computeArticle(){
        // 查询前5天的文章数据
        Date dateParam = DateTime.now().minusDays(5).toDate();
        List<ApArticle> apArticleList = apArticleMapper.findArticleListByLast5Days(dateParam);

        //计算文章分值
        List<HotArticleVo> hotArticleVoList = compute(apArticleList);



        //缓存前30篇文章
        cacheToRedis(hotArticleVoList);
    }

    @Autowired
    private IWemediaClient iWemediaClient;

    @Autowired
    private RedisCache redisCache;

    private void cacheToRedis(List<HotArticleVo> hotArticleVoList) {
        ResponseResult responseResult = iWemediaClient.getChannels();
        if(responseResult.getCode() == 200){
            String jsonStr = JSON.toJSONString(responseResult.getData());
            List<WmChannel> wmChannels = JSON.parseArray(jsonStr, WmChannel.class);
            if(wmChannels != null && wmChannels.size() > 0){
                for (WmChannel wmChannel : wmChannels) {
                    List<HotArticleVo> hotArticleVos = hotArticleVoList.stream().filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList());

                    hotArticleVos = hotArticleVos.stream().sorted(Comparator.comparing(HotArticleVo::getSocre).reversed()).collect(Collectors.toList());
                    if(hotArticleVos.size() > 30){
                        hotArticleVos = hotArticleVos.subList(0,30);
                    }
                    log.info("wmChannel {}, hotArticleVos {}",wmChannel,hotArticleVos.toString());
                    redisCache.set(ArticleConstants.HOT_ARTICLE_FIRST_PAGE+wmChannel.getId().toString(),JSON.toJSONString(hotArticleVos));
                }
            }
            hotArticleVoList = hotArticleVoList.stream().sorted(Comparator.comparing(HotArticleVo::getSocre).reversed()).collect(Collectors.toList());
            if(hotArticleVoList.size() > 30){
                hotArticleVoList = hotArticleVoList.subList(0,30);
            }
            redisCache.set(ArticleConstants.HOT_ARTICLE_FIRST_PAGE+ArticleConstants.DEFAULT_TAG.toString(),JSON.toJSONString(hotArticleVoList));
        }
    }

    public List<HotArticleVo> compute(List<ApArticle> apArticleList){
        List<HotArticleVo> hotArticleVoList = new ArrayList<>();
        if(apArticleList != null && apArticleList.size() > 0){
            for (ApArticle apArticle : apArticleList) {
                HotArticleVo hotArticleVo = new HotArticleVo();
                BeanUtils.copyProperties(apArticle,hotArticleVo);
                Integer score = computeScore(apArticle);
                hotArticleVo.setSocre(score);
                hotArticleVoList.add(hotArticleVo);
            }
        }
        return hotArticleVoList;
    }
    public Integer computeScore(ApArticle apArticle){
        Integer score = 0;
        if(apArticle.getLikes() != null){
            score += apArticle.getLikes() * ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT;
        }
        if (apArticle.getViews() != null) {
            score += apArticle.getViews() * 1;
        }
        if(apArticle.getComment() != null){
            score += apArticle.getComment() * ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT;
        }
        if(apArticle.getCollection() != null){
            score += apArticle.getCollection() * ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT;
        }
        return score;
    }
}
